; Context switching.
; Do not rely on stack frames - leave or not, crash or not.
; Do not care TLS. All work is done serially. No need for locks.

; Prototype:
; void _restart(struct C *prev, struct C *next) __attribute__ ((regparm(2)))

[GLOBAL _restart]
_restart:
    mov     [eax], esp
    mov     [eax+0x4], ebp
    mov     dword [eax+0x8], .bpoint

    mov     esp, [edx]

    jmp     dword [edx+0x8]

.bpoint:
    mov     ebp, [edx+0x4]
    ret


; Get the value of eip for filling a context.
; Actually, it is the bound of the next instruction of the invocation.

; Prototype:
; void *_get_eip(void)

[GLOBAL _get_eip]
_get_eip:
    pop     eax
    jmp     eax


; Entrance to the actual entrance.
; Assumes the argument is on the stack.
; Calls exit_gate by returning.

; Prototype:
; void wrap_gate(void)

[GLOBAL wrap_gate]
wrap_gate:
    pop     eax
    call    eax
    ret
